import * as monaco from 'monaco-editor';

import * as nginx from '../languages/nginx';
import directives from '../languages/nginx/directives.json';
import suggestions from '../languages/nginx/suggestions';
import * as toml from '../languages/toml';

function registerLanguage() {
  // 定义要注册的语言的扩展点对象
  const tomlLanguage = {
    aliases: ['toml', 'TOML'],
    extensions: ['.toml'],
    id: 'toml',
    loader: () => Promise.resolve({}),
    mimetypes: ['application/toml', 'text/x-toml'],
  };
  monaco.languages.register(tomlLanguage);

  const nginxLanguage = {
    aliases: ['nginx', 'NGINX'],
    extensions: ['.nginx', '.nginxconf', '.conf'],
    id: 'nginx',
    loader: () => Promise.resolve({}),
  };
  monaco.languages.register(nginxLanguage);
}

function configMonocaEditor($monaco: typeof monaco) {
  // validation settings
  $monaco?.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: false,
  });
  // compiler options
  $monaco?.languages.typescript.javascriptDefaults.setCompilerOptions({
    allowNonTsExtensions: true,
    strict: true,
    target: monaco.languages.typescript.ScriptTarget.ESNext,
  });

  // 定义要注册的语言的扩展点对象
  const tomlLanguage = {
    aliases: ['toml', 'TOML'],
    extensions: ['.toml'],
    id: 'toml',
    loader: () => Promise.resolve({}),
    mimetypes: ['application/toml', 'text/x-toml'],
  };

  const nginxLanguage = {
    aliases: ['nginx', 'NGINX'],
    extensions: ['.nginx', '.nginxconf', '.conf'],
    id: 'nginx',
    loader: () => Promise.resolve({}),
  };

  // 设置Toml语言
  $monaco.languages.register(tomlLanguage);
  $monaco.languages.setLanguageConfiguration(tomlLanguage.id, toml.conf);
  $monaco.languages.setMonarchTokensProvider(tomlLanguage.id, toml.language);

  // 设置nginx语言
  $monaco.languages.register(nginxLanguage);
  // monaco.languages.setLanguageConfiguration(nginxLanguage.id, nginx.conf);
  $monaco.languages.setMonarchTokensProvider(nginxLanguage.id, nginx.language);
  $monaco.editor.defineTheme('nginx-theme', nginx.themeConfig);
  $monaco.editor.defineTheme('nginx-theme-dark', nginx.themeDarkConfig);
  $monaco.languages.registerCompletionItemProvider('nginx', {
    provideCompletionItems: (
      model: monaco.editor.ITextModel,
      position: monaco.Position,
    ) => {
      const word = model.getWordUntilPosition(position);
      const range = {
        endColumn: word.endColumn,
        endLineNumber: position.lineNumber,
        startColumn: word.startColumn,
        startLineNumber: position.lineNumber,
      };
      return { suggestions: suggestions(range) };
    },
  });
  $monaco.languages.registerHoverProvider('nginx', {
    provideHover: (
      model: monaco.editor.ITextModel,
      position: monaco.Position,
      _token: monaco.CancellationToken,
    ) => {
      const word = model.getWordAtPosition(position);
      if (!word) return;
      const data = directives.find(
        (item) => item.n === word.word || item.n === `$${word.word}`,
      );
      if (!data) return;
      const range = {
        endColumn: word.endColumn,
        endLineNumber: position.lineNumber,
        startColumn: word.startColumn,
        startLineNumber: position.lineNumber,
      };
      const contents = [
        { value: `**\`${data.n}\`** | ${data.m} | ${data.c || ''}` },
      ];
      if (data.s) {
        contents.push({ value: `**syntax:** ${data.s || ''}` });
      }
      if (data.v) {
        contents.push({ value: `**default:** ${data.v || ''}` });
      }
      if (data.d) {
        contents.push({ value: `${data.d}` });
      }
      return {
        contents: [...contents],
        range,
      };
    },
  });
}

export { configMonocaEditor, registerLanguage };
